﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using DiskUsage.CoreLib;
using DiskUsage.CoreLib.MessageBus;

namespace DiskUsage
{
    /// <summary>
    /// Interaction logic for DirectoryTreeView.xaml
    /// </summary>
    public partial class DirectoryListView : UserControl, IRefreshable
    {
        DirectoryInfo m_directoryInfo;

        public DirectoryListView()
        {
            this.InitializeComponent();
            MessageBus<RefreshMessage>.Instance.MessageRecieved += Instance_MessageRecieved;
        }

        void Instance_MessageRecieved(object sender, MessageBusEventArgs<RefreshMessage> e)
        {
            Refresh();
        }

        public DirectoryInfo DirectoryInfo
        {
            get
            {
                return m_directoryInfo;
            }
            set
            {
                m_directoryInfo = value;
                PopulateListView(m_directoryInfo);
            }
        }

        private void PopulateListView(System.IO.DirectoryInfo m_directoryInfo)
        {
            if (m_directoryInfo == null)
            {
                m_listViewDetails.ItemsSource = new List<DirectoryListPresentation>();
                return;
            }

            var source = new List<DirectoryListPresentation>();
            try
            {
                foreach (var dir in m_directoryInfo.GetDirectories())
                    source.Add(new DirectoryListPresentation(dir));
                foreach (var file in m_directoryInfo.GetFiles())
                    source.Add(new DirectoryListPresentation(file));
            }
            catch (UnauthorizedAccessException ex)
            {
                MessageBox.Show(ex.Message, "Access Denied", MessageBoxButton.OK, MessageBoxImage.Error);
                source = new List<DirectoryListPresentation>();
            }
            catch
            {
                source = new List<DirectoryListPresentation>();
            }
            m_listViewDetails.ItemsSource = source;
            if (m_lastHeaderClicked != null)
            {
                Sort(m_lastHeaderClicked.Column.Header as string, m_lastDirection);
            }
        }

        private void Sort(string sortBy, ListSortDirection direction)
        {
            ICollectionView dataView =
              CollectionViewSource.GetDefaultView(m_listViewDetails.ItemsSource);

            dataView.SortDescriptions.Clear();
            SortDescription sd = new SortDescription(sortBy, direction);
            dataView.SortDescriptions.Add(sd);
            dataView.Refresh();
        }

        GridViewColumnHeader m_lastHeaderClicked = null;
        ListSortDirection m_lastDirection = ListSortDirection.Ascending;

        void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader headerClicked =
                  e.OriginalSource as GridViewColumnHeader;
            ListSortDirection direction;

            if (headerClicked != null)
            {
                if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
                {
                    if (headerClicked != m_lastHeaderClicked)
                    {
                        direction = ListSortDirection.Ascending;
                    }
                    else
                    {
                        if (m_lastDirection == ListSortDirection.Ascending)
                        {
                            direction = ListSortDirection.Descending;
                        }
                        else
                        {
                            direction = ListSortDirection.Ascending;
                        }
                    }

                    string header = headerClicked.Column.Header as string;
                    Sort(header, direction);

                    if (direction == ListSortDirection.Ascending)
                    {
                        headerClicked.Column.HeaderTemplate =
                          Resources["HeaderTemplateArrowUp"] as DataTemplate;
                    }
                    else
                    {
                        headerClicked.Column.HeaderTemplate =
                          Resources["HeaderTemplateArrowDown"] as DataTemplate;
                    }

                    // Remove arrow from previously sorted header
                    if (m_lastHeaderClicked != null && m_lastHeaderClicked != headerClicked)
                    {
                        m_lastHeaderClicked.Column.HeaderTemplate = null;
                    }


                    m_lastHeaderClicked = headerClicked;
                    m_lastDirection = direction;
                }
            }
        }

        public void Refresh()
        {
            PopulateListView(m_directoryInfo);
        }

        private void m_listViewDetails_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var item = m_listViewDetails.SelectedItem as DirectoryListPresentation;
            if (item == null || item.DirectoryInfo == null)
                return;
            MessageBus<DirectoryChangedMessage>.Instance.SendMessage(this,
                new DirectoryChangedMessage { OldDir = DirectoryInfo, NewDir = item.DirectoryInfo });
        }

        private void CalculateSize_Click(object sender, RoutedEventArgs e)
        {
            var selectedItem = m_listViewDetails.SelectedItem as DirectoryListPresentation;
            if (selectedItem.DirectoryInfo != null)
                DirectorySizeTreeCreator.CreateTree(selectedItem.DirectoryInfo.FullName);
            else if(selectedItem.FileInfo != null)
                DirectorySizeTreeCreator.CreateTree(selectedItem.FileInfo.FullName);
            Refresh();
        }
    }
}